package com.stem.sms.authenticator;

import com.stem.sms.authenticator.ali.SmsUtils;
import org.keycloak.authentication.AuthenticationFlowContext;
import org.keycloak.authentication.Authenticator;
import org.keycloak.forms.login.LoginFormsProvider;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;

import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;

/**
 * @author zhang
 */
public class SMSAuthenticator implements Authenticator {


    /**
     * 初始化方法
     *
     * @param context 认证流程上下文
     */
    @Override
    public void authenticate(AuthenticationFlowContext context) {
        LoginFormsProvider form = context.form();
        form.setAttribute("status", false);
        Response challenge = form.createForm("sms-validation.ftl");
        context.challenge(challenge);
    }

    /**
     * 处理页面点击事件
     * @param context 上下文
     */
    @Override
    public void action(AuthenticationFlowContext context) {

        SmsUtils smsUtils = new SmsUtils();

        MultivaluedMap<String, String> inputData = context.getHttpRequest().getDecodedFormParameters();
        String phoneNumber = inputData.getFirst("phoneNumber");
        UserModel userByUsername = context.getSession().users().getUserByUsername(phoneNumber, context.getRealm());
        LoginFormsProvider form = context.form();


        if (userByUsername == null) {
            form.setAttribute("errorMessage", "用户名不存在");
            form.setAttribute("status", false);
            Response challenge = form.createForm("sms-validation.ftl");
            context.challenge(challenge);
            return;
        }

        //判断用户是点击发送还是取消
        boolean sendCode = inputData.containsKey("sendCode");
        boolean cancel = inputData.containsKey("cancel");
        if (cancel) {
            form.setAttribute("phoneNumber", "");
            form.setAttribute("status", false);
            Response challenge = form.createForm("sms-validation.ftl");
            context.clearUser();
            context.challenge(challenge);
            return;
        }
        if (sendCode) {
            //发送验证码
            if (smsUtils.send(phoneNumber, context)) {
                form.setAttribute("status", true);
                form.setAttribute("phoneNumber", phoneNumber);
                Response challenge = form.createForm("sms-validation.ftl");
                context.challenge(challenge);
            } else {
                form.setAttribute("errorMessage", "验证码发送失败");
                Response challenge = form.createForm("sms-validation.ftl");
                context.challenge(challenge);
            }
        } else {
            //校验验证码
            context.setUser(userByUsername);
            SmsUtils.CODE_STATUS status = smsUtils.validateCode(context);
            switch (status) {
                case VALID:
                    System.out.println("verify code check : OK");
                    context.success();
                    break;
                case INVALID:
                    Response challenge = form.setAttribute("phoneNumber", phoneNumber)
                            .setAttribute("errorMessage", "验证码不正确")
                            .setAttribute("status", true)
                            .setAttribute("username", context.getAuthenticationSession().getAuthenticatedUser().getUsername())
                            .createForm("sms-validation.ftl");
                    context.challenge(challenge);
                    break;
                default:
                    break;
            }
        }


    }

    @Override
    public boolean requiresUser() {
        return false;
    }

    @Override
    public boolean configuredFor(KeycloakSession session, RealmModel realm, UserModel user) {
        return true;
    }

    @Override
    public void setRequiredActions(KeycloakSession session, RealmModel realm, UserModel user) {

    }

    @Override
    public void close() {
        System.out.println("<<<<<<<<<<<<<<< SMSAuthenticator close");
    }

}
